JavaScript 中的this是根据运行时的环境所决定的
①this在全局作用域中
1 2 3 4 5 6
| foo = 'abc' console.log(foo)
var foo = 'def' console.log(this.foo)
|
②this在函数/对象方法中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| var boat = { size: 'normal', boatInfo: function() { console.log(this === boat, this.size) } }
boat.boatInfo()
var bigBoat = { size: 'big' }
bigBoat.boatInfo = boat.boatInfo bigBoat.boatInfo()
|
首先要明白,在任何函数中,this的指向都不是静态的(static)。它总是在你调用一个函数,但尚未执行函数内部代码前被指定。实际上,this是 被调用的函数的父作用域提供的。
this,指向调用它所属的那个函数的那个对象
- 如果函数左边是一个引用,那么函数里的this指向的就是这个引用
- 否则this指向的就是全局对象(浏览器 -> window)
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| function bar() { console.log(this) } bar()
var foo = { baz: function() { console.log(this) } } foo.baz()
|
由于js中Object和Function是引用类型,所以在引用发生变化的时候,this的指向也会发生改变
1 2 3 4 5 6 7 8 9 10
| var foo = { baz: function() { console.log(this) } } foo.baz()
var anotherBaz = foo.baz anotherBaz()
|
嵌套在对象里的this的指向
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| var anum = 0
var foo = { anum: 10, baz: { anum: 20, bar: function() { console.log(this.anum) } } } foo.baz.bar()
var hello = foo.baz.bar; hello()
|
值得注意的是下面这几种用法,都会改变this的指向。
1 2 3 4 5 6 7 8 9 10 11 12 13
| var obj ={ foo: function () { console.log(this) } }
obj.foo()
;(obj.foo = obj.foo)()
;(false || obj.foo)()
;(1, obj.foo)()
|
上面代码中,obj.foo就是一个值。这个值真正调用的时候,运行环境已经不是obj了,而是全局环境,所以this不再指向obj
- 可以这样理解,JavaScript 引擎内部,obj和obj.foo储存在两个内存地址,称为地址一和地址二。
- obj.foo()这样调用时,是从地址一调用地址二,因此地址二的运行环境是地址一,this指向obj。
- 但是,上面三种情况,都是直接取出地址二进行调用,这样的话,运行环境就是全局环境,因此this指向全局环境。
上面三种情况等同于下面的代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| (obj.foo = function () { console.log(this) })()
(function () { console.log(this) })()
(false || function () { console.log(this) })()
(1, function () { console.log(this) })()
|
如果this所在的方法不在对象的第一层,这时this只是指向当前一层的对象,而不会继承更上面的层。
1 2 3 4 5 6 7 8 9 10
| var obj = { name: 'Hello', son: { foo: function() { console.log(this.name) } } }
obj.son.foo()
|
此时的this指向的son,son没有name属性,就当然undefined了
③this在构造函数和类中
构造函数中的this,指的是实例对象。
1 2 3 4 5 6 7 8 9 10 11
| var Obj = function (x) { this.x = x function sayHi() { console.log(this.x) } } Obj.prototype.sayHi = function () { console.log(this.x) } var obj1 = new Obj('Hello World!') obj1.sayHi()
|
类中的this,指的是实例对象。
1 2 3 4 5 6 7 8 9 10
| class Obj { constructor(x) { this.x = x; } sayHi() { console.log(this.x) } } var obj1 = new Obj('Hello World!') obj1.sayHi()
|
④this在dom事件中
1 2 3 4 5 6 7 8 9 10 11 12 13
| <div id="test">今天是个好日子</div> <script> var myElem = document.getElementById('test') myElem.onclick = function() { console.log(this.innerHTML) }
myElem.onclick() </script> 😑😶😏😣😥😮😯😍😘😗😙😚 <button onclick="this.style.display='none'"> 点我后我就消失了 </button>
|
参考资料
阮一峰 JavaScript入门教程
日暮乡关 有道云笔记
菜鸟教程 Javascript教程
注:本文不以盈利为目的,仅做学习交流使用,若有侵权,请联系我删除,万分感谢!